UE.registerUI('aiwrite', function (editor, uiName) {
    var items = [];
    items.push({
        label: "AI 续写",
        value: 0,
        className:'edui-for-aiwrite-1',
        theme: editor.options.theme,
        onclick: function () {
            editor.selection.getRange().select();
            var selectedText = editor.selection.getText();
            if(selectedText){
                var promise = editor.options.aiModelUrlCreate();
                promise.then(res => {
                    if(res.code === 0){
                        var prompt = "请帮忙继续扩展续写这段内容，并返回结果";
                        var processor = new EditorMessageProcessor(editor);
                        var socket = new AiWriteWebSocket(res.data.url, processor, res.data.appId, res.data.version);
                        socket.start(`${selectedText}\n${prompt}`);
                    }
                });
            }
        }
    });
    items.push({
        label: "AI 优化",
        value: 1,
        className:'edui-for-aiwrite-2',
        theme: editor.options.theme,
        onclick:function () {
            editor.selection.getRange().select();
            var selectedText = editor.selection.getText();
            if(selectedText){
                var promise = editor.options.aiModelUrlCreate();
                promise.then(res => {
                    if(res.code === 0){
                        var prompt = "请帮忙优化一下这段文字的内容，并返回结果";
                        var processor = new EditorMessageProcessor(editor);
                        var socket = new AiWriteWebSocket(res.data.url, processor, res.data.appId, res.data.version);
                        socket.start(`${selectedText}\n${prompt}`);
                    }
                });
            }
        }
    });
    items.push({
        label: "AI 校对",
        value: 2,
        className:'edui-for-aiwrite-3',
        theme: editor.options.theme,
        onclick:function () {
            editor.selection.getRange().select();
            var selectedText = editor.selection.getText();
            if(selectedText){
                var promise = editor.options.aiModelUrlCreate();
                promise.then(res => {
                    if(res.code === 0){
                        var prompt = "请帮忙找出这段话的错别字或词语，把错别字或词语修改后，并返回结果，不要解释或其他多余的内容果";
                        var processor = new EditorMessageProcessor(editor);
                        var socket = new AiWriteWebSocket(res.data.url, processor, res.data.appId, res.data.version);
                        socket.start(`${selectedText}\n${prompt}`);
                    }
                });
            }
        }
    });
    items.push({
        label: "AI 翻译",
        value: 3,
        className:'edui-for-aiwrite-4',
        theme: editor.options.theme,
        onclick: function () {
            editor.selection.getRange().select();
            var selectedText = editor.selection.getText();
            if(selectedText){
                var promise = editor.options.aiModelUrlCreate();
                promise.then(res => {
                    if(res.code === 0){
                        var prompt = "请帮忙把这段内容翻译为英语，直接返回英语结果";
                        var processor = new EditorMessageProcessor(editor);
                        var socket = new AiWriteWebSocket(res.data.url, processor, res.data.appId, res.data.version);
                        socket.start(`${selectedText}\n${prompt}`);
                    }
                });
            }
        }
    });

    editor.registerCommand(uiName, {
        execCommand: function () {

        }
    });

    // 创建自定义工具栏按钮
    var btn = new UE.ui.MenuButton({
        editor: editor,
        className:'edui-for-aiwrite',
        name: 'aiwrite',//AI写作助手
        title: 'AI',
        items: items,
        onbuttonclick: function () {
            editor.execCommand("aiwrite", -1);
        }
    });

    //当点到编辑内容上时，按钮要做的状态反射
    editor.addListener('selectionchange', function() {
        var state = editor.queryCommandState(uiName);
        if (state == -1) {
            btn.setDisabled(true);
            btn.setChecked(false);
        } else {
            btn.setDisabled(false);
            btn.setChecked(state);
        }
    });

    function AiWriteWebSocket(url, processor, appId, version) {
        return {
            "url": url,
            "processor": processor,
            "webSocket": void 0,
            "isOpen": false,
            "text": '',
            "listeners": [],
            "appId": appId,
            addListener: function (listener) {
                this.listeners.push(listener);
            },
            start: function (text) {
                for (let listener of this.listeners) {
                    listener.onStart();
                }
    
                this.text = text;
                this.webSocket = new WebSocket(this.url);
                this.webSocket.onopen = (e) => this.onOpen(e)
                this.webSocket.onmessage = (e) => this.onMessage(e)
                this.webSocket.onclose = (e) => this.onClose(e)
                this.webSocket.onerror = (e) => this.onError(e)
    
                for (let listener of this.listeners) {
                    listener.onStop();
                }
            },
            send: function (message) {
                const object = {
                    "header": {
                        "app_id": this.appId,
                        "uid": uuid(),
                    },
                    "parameter": {
                        "chat": {
                            "domain": this.getDomain(),
                            "temperature": 0.5,
                            "max_tokens": 2048,
                        }
                    },
                    "payload": {
                        "message": {
                            "text": []
                        }
                    }
                }
    
                object.payload.message.text.push(
                    {"role": "user", "content": message}
                )
    
                if (this.webSocket && this.isOpen) {
                    this.webSocket.send(JSON.stringify(object));
                }
            },
            onOpen (e) {
                this.isOpen = true;
                if (this.text) {
                    this.send(this.text);
                }
            },
            onMessage(e) {
                if (this.processor) {
                    this.processor.onMessage(e.data);
                }
            },
            onClose (e) {
                this.isOpen = false;
                for (let listener of this.listeners) {
                    listener.onStop();
                }
            },
            onError (e) {
                this.isOpen = false;
                for (let listener of this.listeners) {
                    listener.onStop();
                }
            },
            getDomain: function () {
                switch (this.version) {
                    case "v3.1":
                        return "generalv3";
                    case "v2.1":
                        return "generalv2";
                    default:
                        return "general";
                }
            }
        }
    }
    
    function EditorMessageProcessor(editor) {
        return {
            onMessage: function (data) {
                let message = JSON.parse(data);
                let text = message.payload.choices.text[0].content;
                if (text) {
                    text = text.replace(/\n\n/g, '<br>');
                    text = text.replace(/\n/g, '<br>');
                    editor.focus();
                    editor.execCommand("insertHTML", text);
                }
                if (message.header.status == 2) {
                    // 结束
                }
            }
        }
    }
    
    function uuid() {
        return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) =>
            (c ^ window.crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        ).replace(/-/g,"");
    }
    return btn;
});